package cn.taobaoke.restful.service;

import cn.taobaoke.restful.domain.UserEntity;
import cn.taobaoke.restful.domain.UserRepository;
import cn.taobaoke.restful.exception.TBKException;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import lombok.val;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Repository;

import java.util.*;

/**
 * @author yangzuo
 * @since 2017-03-15
 */
@Repository
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class UserService {

    public List<UserEntity> getUsersInGroup(final Long groupId, final Long domainId) {
        return userRepository.findUsersInGroup(groupId, domainId);
    }

    /**
     * @param userId
     */
    public void checkUserExistByUserId(final Long userId, final Long domainId) {
        val entityOpt = userRepository.findByIdAndDomainId(userId, domainId);
        if (! entityOpt.isPresent()) {
            throw new TBKException("用户ID[" + userId + "]不存在");
        }
    }

    public Page<UserEntity> search(String keyword, Long agentId, Pageable pageable, final Long domainId) {
        keyword = keyword == null ? "" : keyword;

        if (agentId == null) {
            return userRepository.findByKeyword(keyword, pageable, domainId);
        } else {
            return userRepository.findPagingUsersForAgentById(keyword, agentId, pageable, domainId);
        }
    }

    /**
     * 插入新用户
     *
     * @param userEntity
     * @return
     */
    public UserEntity addUserEntity(final UserEntity userEntity, final Long domainId) {
        val entityOpt = userRepository.findByWeChatAndDomainId(userEntity.getWeChat(), domainId);
        if (entityOpt.isPresent()) {
            logger.warn("insertUserEntity：[{}]已经存在", userEntity.getWeChat());
            throw new TBKException("用户名 [" + userEntity.getWeChat() + "] 已经存在");
        }
        userEntity.setId(null);
        userEntity.setCreateTime(new Date());
        userEntity.setDomainId(domainId);
        return userRepository.save(userEntity);
    }


    /**
     * 当不存在该用户时候,则创建相关用户
     *
     * @param userEntities
     * @return userlist        返回带用户Id的列表
     */
    public List<UserEntity> createUserIfNameNotExist(List<UserEntity> userEntities, final Long domainId) {
        if (userEntities == null || userEntities.isEmpty()) return Collections.EMPTY_LIST;

        val names = new ArrayList<String>();
//        userEntities.forEach(user -> names.add(user.getName()));
//        List<String> names = userEntities.stream().map(user -> user.getName()).collect(Collectors.toList());
        for (UserEntity user : userEntities) {
            names.add(user.getName());
        }

        List<UserEntity> existUsers = userRepository.findByDomainIdAndNameIn(domainId, names);

        val nameMapUser = new HashMap<String, UserEntity>();
        if (existUsers != null && existUsers.size() > 0) {
            existUsers.forEach(user -> nameMapUser.put(user.getName(), user));
        }

        List<UserEntity> notExists = new ArrayList<>(userEntities.size());

        for (UserEntity user : userEntities) {
            if (!nameMapUser.containsKey(user.getName())) {
                user.setCreateTime(new Date());
                user.setModifiedTime(new Date());
                user.setDomainId(domainId); // important
                notExists.add(user);
            }
        }

        if (notExists.size() > 0) {
            notExists = userRepository.saveAll(notExists);
            notExists.forEach(user -> nameMapUser.put(user.getName(), user));
        }

        val result = new ArrayList<UserEntity>();
        for (UserEntity user : userEntities) {
            result.add(nameMapUser.get(user.getName()));
        }
        return result;

//        return userEntities.stream().map(user -> nameMapUser.get(user.getName())).collect(Collectors.toList());
    }


    private final @NonNull UserRepository userRepository;

    private static Logger logger = LogManager.getLogger(UserService.class);
}
